
/* <<< COPYRIGHT START >>>
 * Copyright 2006-Present OxygenSoftwareLibrary.com
 * Licensed under the GNU Lesser General Public License.
 * http://www.gnu.org/licenses/lgpl.html
 * 
 * @author: Ugorji Dick-Nwoke
 * <<< COPYRIGHT END >>>
 */


package oxygen.tool.wlfacade.helpers;

import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.management.ObjectName;

import oxygen.tool.wlfacade.WLConnectionData;
import oxygen.tool.wlfacade.WLFacadeContextHelper;
import oxygen.tool.wlfacade.WLJMXHandler;
import oxygen.tool.wlfacade.WLMBSTree;
import oxygen.tool.wlfacade.WLScriptHelper;
import oxygen.util.OxyTable;
import oxygen.util.ProcessHandler;
import weblogic.management.deploy.DeploymentData;
import weblogic.management.runtime.DeploymentTaskRuntimeMBean;
import weblogic.management.runtime.TaskRuntimeMBean;

/*
 * Refactor to use just straight JMX
 */
public class WLDeploy {
  private static ObjectName getDeployerRuntime(WLFacadeContextHelper wlctx) throws Exception {
    WLScriptHelper.ensureMBSTree(wlctx);
    WLMBSTree wltree = (WLMBSTree)wlctx.getCurrentTree();
    WLJMXHandler dmhdlr = wltree.getJMXHandler();
    ObjectName pattern = dmhdlr.getLookupPattern(wltree.getDomain(), "DeployerRuntime=DeployerRuntime");
    return WLScriptHelper.getSingleObjName
      (WLScriptHelper.getObjNames(wltree.getMBS(), pattern, dmhdlr, null, false, null));
  }
  
  public static ObjectName gotodeployruntime(WLFacadeContextHelper wlctx) throws Exception {
    WLScriptHelper.ensureConnected(wlctx);
    WLScriptHelper.ensureAdminServer(wlctx);
    WLScriptHelper.ensureMBSTree(wlctx);
    WLMBSTree wltree = (WLMBSTree)wlctx.getCurrentTree();
    wltree.setPointer(getDeployerRuntime(wlctx));
    return (ObjectName)wltree.pointer();
  }
  
  public static void uploadfiles(WLFacadeContextHelper wlctx, 
                                 String name, String source, String[] files) 
    throws Exception {
    WLConnectionData wlconn = wlctx.getWLConnectionData();
    String cmdline = "java weblogic.Deployer " + 
      " -adminurl " + wlconn.url + 
      " -username " + wlconn.username + 
      " -password " + wlconn.password + 
      " -upload " + 
      " -source " + source + 
      " -name " + name;
    if(files != null && files.length > 0) {
      StringBuffer buf = new StringBuffer(cmdline);
      for(int i = 0; i < files.length; i++) {
        buf.append(" ").append(files[i]);
      }
      cmdline = buf.toString();
    }
    Process p = Runtime.getRuntime().exec(cmdline);
    ProcessHandler.handle(p, System.out, null, true);
  }
  
  public static OxyTable deploytasks(WLFacadeContextHelper wlctx)
    throws Exception {
    WLScriptHelper.ensureConnected(wlctx);
    WLScriptHelper.ensureAdminServer(wlctx);
    Object mbs = wlctx.getConnection().getChangeMBS();
    ObjectName dmb = getDeployerRuntime(wlctx);
    DeploymentTaskRuntimeMBean[] taskmbs = 
      (DeploymentTaskRuntimeMBean[])WLScriptHelper.mbs_invoke
      (mbs, dmb, "list", new Object[0]);
    return todeploytable(wlctx, taskmbs);
  }
  
  public static OxyTable deploytaskinfo(WLFacadeContextHelper wlctx, String id)
    throws Exception {
    WLScriptHelper.ensureConnected(wlctx);
    WLScriptHelper.ensureAdminServer(wlctx);
    Object mbs = wlctx.getConnection().getChangeMBS();
    ObjectName dmb = getDeployerRuntime(wlctx);
    DeploymentTaskRuntimeMBean taskmb = (DeploymentTaskRuntimeMBean)
      WLScriptHelper.mbs_invoke(mbs, dmb, "query", new Object[]{id});
    return todeploytable(wlctx, taskmb);
  }
  
  public static DeploymentData deploydata
    (WLFacadeContextHelper wlctx, String[] targets, String[] files, boolean deletefiles, int timeout)
    throws Exception {
    HashMap map = new HashMap();
    for(int i = 0; i < targets.length; i++) {
      map.put(targets[i], null);
    }
    return deploydata(wlctx, map, files, deletefiles, timeout);
  }
  
  public static DeploymentData deploydata
    (WLFacadeContextHelper wlctx, Map targets, String[] files, boolean deletefiles, int timeout)
    throws Exception {
    DeploymentData ddata = new DeploymentData(files);
    if(timeout != -1) {
      ddata.setTimeOut(timeout);
    }
    if(deletefiles) {
      ddata.setDelete(true);
    }
    for(Iterator itr = targets.keySet().iterator(); itr.hasNext(); ) {
      String target = (String)itr.next();
      String[] modules = (String[])targets.get(target);
      ddata.addTarget(target, modules);
    }    
    return ddata;
  }
  
  public static OxyTable deployer
    (WLFacadeContextHelper wlctx, String action, 
     String source, String name, String stagingmode, String id, 
     DeploymentData ddata, boolean starttask)
    throws Exception {
    WLScriptHelper.ensureConnected(wlctx);
    WLScriptHelper.ensureAdminServer(wlctx);
    Object mbs = wlctx.getConnection().getChangeMBS();
    
    ObjectName dmb = getDeployerRuntime(wlctx);
    DeploymentTaskRuntimeMBean taskmb = null;
    String[] allsignatures = new String[]
      {"java.lang.String", "java.lang.String", "java.lang.String", 
       "weblogic.management.deploy.DeploymentData", 
       "java.lang.String", "boolean"};
    if(action.equals("deploy") || 
       action.equals("activate")) {
      Object[] args = new Object[]{source, name, stagingmode, ddata, id, new Boolean(starttask)};
      ArrayList al = new ArrayList();
      al.addAll(Arrays.asList(allsignatures));
      String[] signatures = (String[])al.toArray(new String[0]);
      taskmb = (DeploymentTaskRuntimeMBean)WLScriptHelper.mbs_invoke(mbs, dmb, action, args, signatures);
    } else if(action.equals("distribute")) {
      Object[] args = new Object[]{source, name, ddata, id, new Boolean(starttask)};
      ArrayList al = new ArrayList();
      al.addAll(Arrays.asList(allsignatures));
      al.remove(2);
      String[] signatures = (String[])al.toArray(new String[0]);
      taskmb = (DeploymentTaskRuntimeMBean)WLScriptHelper.mbs_invoke(mbs, dmb, action, args, signatures);
    } else if(action.equals("undeploy") || 
              action.equals("redeploy") || 
              action.equals("remove") || 
              action.equals("start") || 
              action.equals("stop")) {
      Object[] args = new Object[]{name, ddata, id, new Boolean(starttask)};
      ArrayList al = new ArrayList();
      al.addAll(Arrays.asList(allsignatures));
      al.remove(1);
      al.remove(0);
      String[] signatures = (String[])al.toArray(new String[0]);
      taskmb = (DeploymentTaskRuntimeMBean)WLScriptHelper.mbs_invoke(mbs, dmb, action, args, signatures);
    } else if(action.equals("stop") || 
              action.equals("deactivate")) {
      Object[] args = new Object[]{name, ddata, id};
      ArrayList al = new ArrayList();
      al.addAll(Arrays.asList(allsignatures));
      al.remove(5);
      al.remove(1);
      al.remove(0);
      String[] signatures = (String[])al.toArray(new String[0]);
      taskmb = (DeploymentTaskRuntimeMBean)WLScriptHelper.mbs_invoke(mbs, dmb, action, args, signatures);
    } else if(action.equals("cancel")) {
      String[] signatures = new String[]{"java.lang.String"};
      Object[] args = new Object[]{id};
      taskmb = (DeploymentTaskRuntimeMBean)WLScriptHelper.mbs_invoke(mbs, dmb, "query", args, signatures);
      taskmb.cancel();
    } 
    return todeploytable(wlctx, taskmb);    
  }
  
  public static void canceldeployment(WLFacadeContextHelper wlctx, String id) throws Exception {
    ObjectName dmb = getDeployerRuntime(wlctx);
    Object mbs = wlctx.getConnection().getChangeMBS();
    String[] signatures = new String[]{"java.lang.String"};
    Object[] args = new Object[]{id};
    TaskRuntimeMBean taskmb = (TaskRuntimeMBean)WLScriptHelper.mbs_invoke(mbs, dmb, "query", args, signatures);
    taskmb.cancel();
  }
  
  public static void canceldeployment(WLFacadeContextHelper wlctx, DeploymentTaskRuntimeMBean taskmb) throws Exception {
    taskmb.cancel();
  }
  
  public static OxyTable todeploytable(WLFacadeContextHelper wlctx, DeploymentTaskRuntimeMBean taskmb) 
    throws Exception {
    Map m = new HashMap();
    m.put("ID", taskmb.getId());
    m.put("Application", taskmb.getApplicationName());
    m.put("Source", taskmb.getSource());
    m.put("Targets", Arrays.asList(taskmb.getTargets()));
    OxyTable tabl = OxyTable.parseFrom(m);
    tabl.setInternalObject(taskmb);
    return tabl;
  }
  
  public static OxyTable todeploytable(WLFacadeContextHelper wlctx, List taskmbslist) 
    throws Exception {
    DeploymentTaskRuntimeMBean[] taskmbs = new DeploymentTaskRuntimeMBean[0];
    if(taskmbslist != null) {
      taskmbs = (DeploymentTaskRuntimeMBean[])taskmbslist.toArray(taskmbs);
    }
    return todeploytable(wlctx, taskmbs);
  }
  
  public static OxyTable todeploytable(WLFacadeContextHelper wlctx, DeploymentTaskRuntimeMBean[] taskmbs) 
    throws Exception {
    String[] headers = new String[]{"ID", "Application", "Source", "Targets"};
    Object[] row = new Object[headers.length];
    OxyTable tabl = new OxyTable(headers);
    tabl.setInternalObject(taskmbs);
    for(int i = 0; i < taskmbs.length; i++) {
      row[0] = taskmbs[i].getId();
      row[1] = taskmbs[i].getApplicationName();
      row[2] = taskmbs[i].getSource();
      row[3] = Arrays.asList(taskmbs[i].getTargets());
      tabl.addRow(row);
    }
    return tabl;
  }

}

